🎖️GitЯра🎖️
Commit 67b3740c822b619c6557890e06e4a8fae4861be4
Parents : 8657232
Author : James Rich <2199651+jamesarich@users.noreply.github.com>
Signature : Signature validation error
Date : 2026-07-15T07:12:36-05:00
Committer : GitHub <noreply@github.com>
Date : 2026-07-15T12:12:36Z
fix: adopt 2024 EPA PM2.5 AQI breakpoints for cross-platform alignment (#6273)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Changes
2 files changed, 23 insertions(+), 14 deletions(-)
Diff
diff --git a/core/model/src/commonMain/kotlin/org/meshtastic/core/model/util/AirQualityIndex.kt b/core/model/src/commonMain/kotlin/org/meshtastic/core/model/util/AirQualityIndex.kt
index 3cbed9d7c3..cd0556ab9d 100644
--- a/core/model/src/commonMain/kotlin/org/meshtastic/core/model/util/AirQualityIndex.kt
+++ b/core/model/src/commonMain/kotlin/org/meshtastic/core/model/util/AirQualityIndex.kt
@@ -84,15 +84,17 @@ object AirQualityIndex {
val aqiHigh: Int,
)
- // Standard EPA PM2.5 (µg/m³) breakpoint table.
+ // Current (2024) EPA PM2.5 24-hour breakpoint table (AQS parameter 88101), µg/m³.
+ // Kept in lockstep with iOS (meshtastic/Meshtastic-Apple#2075) for cross-platform AQI alignment
+ // (meshtastic/design#54).
private val BREAKPOINTS =
listOf(
- Breakpoint(0.0, 12.0, 0, 50),
- Breakpoint(12.1, 35.4, 51, 100),
+ Breakpoint(0.0, 9.0, 0, 50),
+ Breakpoint(9.1, 35.4, 51, 100),
Breakpoint(35.5, 55.4, 101, 150),
- Breakpoint(55.5, 150.4, 151, 200),
- Breakpoint(150.5, 250.4, 201, 300),
- Breakpoint(250.5, 500.4, 301, 500),
+ Breakpoint(55.5, 125.4, 151, 200),
+ Breakpoint(125.5, 225.4, 201, 300),
+ Breakpoint(225.5, 325.4, 301, 500),
)
/**
diff --git a/core/model/src/commonTest/kotlin/org/meshtastic/core/model/util/AirQualityIndexTest.kt b/core/model/src/commonTest/kotlin/org/meshtastic/core/model/util/AirQualityIndexTest.kt
index ab3fc91964..c967d25a1b 100644
--- a/core/model/src/commonTest/kotlin/org/meshtastic/core/model/util/AirQualityIndexTest.kt
+++ b/core/model/src/commonTest/kotlin/org/meshtastic/core/model/util/AirQualityIndexTest.kt
@@ -27,21 +27,28 @@ private const val EPSILON = 0.001
class AirQualityIndexTest {
- // EPA PM2.5 breakpoint table reference values (concentration -> AQI).
+ // Current (2024) EPA PM2.5 24-hour breakpoint table reference values (concentration -> AQI).
@Test
fun pm25ToAqi_matches_epa_breakpoint_table() {
assertEquals(0, AirQualityIndex.pm25ToAqi(0.0))
- assertEquals(50, AirQualityIndex.pm25ToAqi(12.0))
- assertEquals(51, AirQualityIndex.pm25ToAqi(12.1))
+ assertEquals(50, AirQualityIndex.pm25ToAqi(9.0))
+ assertEquals(51, AirQualityIndex.pm25ToAqi(9.1))
assertEquals(100, AirQualityIndex.pm25ToAqi(35.4))
assertEquals(101, AirQualityIndex.pm25ToAqi(35.5))
assertEquals(150, AirQualityIndex.pm25ToAqi(55.4))
assertEquals(151, AirQualityIndex.pm25ToAqi(55.5))
- assertEquals(200, AirQualityIndex.pm25ToAqi(150.4))
- assertEquals(201, AirQualityIndex.pm25ToAqi(150.5))
- assertEquals(300, AirQualityIndex.pm25ToAqi(250.4))
- assertEquals(301, AirQualityIndex.pm25ToAqi(250.5))
- assertEquals(500, AirQualityIndex.pm25ToAqi(500.4))
+ assertEquals(200, AirQualityIndex.pm25ToAqi(125.4))
+ assertEquals(201, AirQualityIndex.pm25ToAqi(125.5))
+ assertEquals(300, AirQualityIndex.pm25ToAqi(225.4))
+ assertEquals(301, AirQualityIndex.pm25ToAqi(225.5))
+ assertEquals(500, AirQualityIndex.pm25ToAqi(325.4))
+ }
+
+ // Regression for meshtastic/design#54: PM2.5 = 10 µg/m³ was "42, Good" on the legacy table;
+ // on the 2024 table it must be "53, Moderate", matching iOS (meshtastic/Meshtastic-Apple#2075).
+ @Test
+ fun pm25ToAqi_uses_2024_breakpoints_for_low_concentrations() {
+ assertEquals(53, AirQualityIndex.pm25ToAqi(10.0))
}
@Test
Served by rngit 1.5.2 - Generated in 0.12s